using GEM.Application.Common;
using GEM.Application.Dto.Role;
using GEM.Application.Repositories;
using GEM.Domain.Entities.App;
using GEM.Domain.Repositories;

namespace GEM.Application.Services;

public class RoleService : IRoleService
{
    private readonly IDapperRepository<AppRole> _IDapperRoleRep;
    private readonly IDapperRepository<AppUser> _IDapperUserRep;
    private readonly IDapperRepository<AppPermission> _IDapperPermissionRep;
    private readonly IRepository<AppUser> _IEfUserRep;
    private readonly IRepository<AppRole> _IEfRoleRep;
    private readonly IRepository<AppPermission> _IEfPermissionRep;

    //依赖注入
    public RoleService(IDapperRepository<AppPermission> IDapperPermissionRep, IRepository<AppPermission> IEfPermissionRep, IRepository<AppRole> IEfRoleRep, IRepository<AppUser> IEfUserRep, IDapperRepository<AppRole> IDapperRoleRep, IDapperRepository<AppUser> IDapperUserRep)
    {
        _IDapperRoleRep = IDapperRoleRep;
        _IDapperUserRep = IDapperUserRep;
        _IEfUserRep = IEfUserRep;
        _IEfRoleRep = IEfRoleRep;
        _IEfPermissionRep = IEfPermissionRep;
        _IDapperPermissionRep = IDapperPermissionRep;
    }

    //分配权限
    public async Task<dynamic> AssignPermissionAsync(Guid RoleId, Guid PermissionId)
    {
        var role = await _IEfRoleRep.GetRoleWithPermissionsAsync(RoleId);
        if (role == null)
        {
            return ApiResponse<string>.Fail(4001, "角色不存在，请确认后重试!!");
        }
        var permission = await _IEfPermissionRep.GetPermissionWithRolesAsync(PermissionId);
        if (permission == null)
        {
            return ApiResponse<string>.Fail(4002, "权限不存在，请确认后重试!!");
        }
        var isTrue = role.AssignPermission(permission);
        if (isTrue)
        {
            await _IEfRoleRep.UpdateAsync(role);
            return ApiResponse<string>.Success($"添加{permission.PermissionName}权限成功");
        }
        return ApiResponse<string>.Fail(4003, $"该角色已有{permission.PermissionName}权限，无需重复分配权限!!");
    }

    //创建角色
    public async Task<dynamic> CreateRoleAsync(string roleName, string dataScope)
    {
        var roles = await _IDapperRoleRep.GetAllAsync();
        //检查角色是否已经存在
        var exists = roles.Any(x => x.RoleName == roleName);
        if (exists)
        {
            return ApiResponse<string>.Fail(4004, $"{roleName}角色已存在,无需创建!!");
        }
        var role = new AppRole { Id = Guid.NewGuid(), RoleName = roleName, DataScope = dataScope };
        var number = await _IDapperRoleRep.CreateAsync(role);
        if (number > 0)
        {
            return ApiResponse<AppRole>.Success(role);
        }
        return ApiResponse<string>.Fail(4040, "创建角色失败");
    }

    public async Task<dynamic> DisableRoleAsync(Guid roleId)
    {
        var role = await _IDapperRoleRep.GetByIdAsync(roleId);
        if (role == null)
        {
            return ApiResponse<string>.Fail(1004, "角色不存在,请确认后重试!!");
        }
        if (role.IsDeleted == true)
        {
            return ApiResponse<string>.Fail(1004, "该角色已删除,请确认后重试!!");
        }
        if (role.IsActived == false)
        {
            return ApiResponse<string>.Fail(1004, "角色已禁用,无需重复禁用");
        }
        role.IsActived = false;
        role.UpdatedAt = DateTime.Now;
        var number = await _IDapperRoleRep.UpdateAsync(role);
        if (number > 0)
        {
            return ApiResponse<string>.Success("禁用成功");
        }
        return ApiResponse<string>.Fail(1004, "禁用失败,请重试!!");
    }

    public async Task<dynamic> EnableRoleAsync(Guid roleId)
    {
        var role = await _IDapperRoleRep.GetByIdAsync(roleId);
        if (role == null)
        {
            return ApiResponse<string>.Fail(1004, "角色不存在,请确认后重试!!");
        }
        if (role.IsDeleted == true)
        {
            return ApiResponse<string>.Fail(1004, "该角色已删除,请确认后重试!!");
        }
        if (role.IsActived == true)
        {
            return ApiResponse<string>.Fail(1004, "角色已启用,无需重复启用");
        }
        role.IsActived = true;
        role.UpdatedAt = DateTime.Now;
        var number = await _IDapperRoleRep.UpdateAsync(role);
        if (number > 0)
        {
            return ApiResponse<string>.Success("启用成功");
        }
        return ApiResponse<string>.Fail(1004, "启用失败,请重试!!");
    }

    public async Task<PagedResult<RoleDto>> GetRolePagedAsync(int pageIndex, int pageSize)
    {
        var (roles, totalCount) = await _IEfRoleRep.GetPagedAsync(pageIndex, pageSize, r => r.AppPermissions);
        var roleDto = roles.Select(role => new RoleDto(
            role.Id,
            role.RoleName,
            role.DataScope,
            role.AppPermissions.Select(p => p.PermissionName).ToList(),
            role.IsActived,
            role.IsDeleted,
            role.CreatedAt,
            role.UpdatedAt
        )).ToList();
        var pagedResult = new PagedResult<RoleDto>
        {
            Items = roleDto,
            TotalCount = totalCount,
            PageIndex = pageIndex,
            PageSize = pageSize
        };
        return pagedResult;

    }

    // 移除角色的指定权限
    public async Task<dynamic> RemovePermissionAsync(Guid RoleId, Guid PermissionId)
    {
        var role = await _IEfRoleRep.GetRoleWithPermissionsAsync(RoleId);
        if (role == null)
        {
            return ApiResponse<string>.Fail(4001, "角色不存在，请确认后重试!!");
        }
        var permission = await _IEfPermissionRep.GetPermissionWithRolesAsync(PermissionId);
        if (permission == null)
        {
            return ApiResponse<string>.Fail(4002, "权限不存在，请确认后重试!!");
        }
        var isTrue = role.RemovePermission(permission);
        if (isTrue)
        {
            await _IEfRoleRep.UpdateAsync(role);
            return ApiResponse<string>.Success($"移除{permission.PermissionName}权限成功");
        }
        return ApiResponse<string>.Fail(4003, "移除权限失败，请稍后重试!!");
    }

    /// <summary>
    /// 删除角色时也会删掉关联表对应的数据(比如用户角色关联表，角色权限关联表)
    /// </summary>
    /// <param name="roleId"></param>
    public async Task<dynamic> RemoveRoleAsync(Guid roleId)
    {
        var role = await _IEfRoleRep.GetByIdAsync(roleId);
        if (role == null)
        {
            return ApiResponse<string>.Fail(4001, "角色不存在，请确认后重试!!");
        }
        await _IEfRoleRep.DeleteAsync(role);
        return ApiResponse<string>.Success("删除成功");
    }


}